//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   Mesh.hh
 * \author Jeremy Roberts
 * \date   05/23/2011
 * \brief  Mesh member definitions.
 * \note   Copyright (C) Jeremy Roberts, but based on T. Evan's Denovo.
 */
//---------------------------------------------------------------------------//
// $Rev::                                               $:Rev of last commit
// $Author::                                            $:Author of last commit
// $Date::                                              $:Date of last commit
//---------------------------------------------------------------------------//

#ifndef MESH_HH
#define MESH_HH

#include <vector>
#include "tran/SlabtranInput.hh"
#include "tran/SlabtranElement.hh"
#include "tran/Definitions.hh"
#include "../utilities/DBC.hh"
#include "../utilities/SP.hh"
#include "../utilities/Vector_Lite.hh"

namespace slabtran
{

//===========================================================================//
/*!
 * \class Mesh
 * \brief 1D/2D/3D orthogonal mesh for SLABTRAN
 *
 * This is a templated class for building a 1D/2D/3D Cartesian class.
 * The mesh is defined via user input in terms of coarse meshes within which
 * a specified number of fine meshes are generated.  Within a coarse mesh,
 * all materials and external sources are uniform.
 *
 */
//===========================================================================//

template <int N>
class Mesh 
{

public:
	//@{
	//! Useful typedefs for classes that use mesh
	typedef typename util::SP<Mesh<N> >					 	SP_mesh;
	typedef SlabtranInput::SP_input 		 				SP_input;
	typedef SlabtranElement::SP_element		 				SP_element;
	typedef std::vector<double>              				Vec_Dbl;
	typedef std::vector<int>                 				Vec_Int;
	typedef unsigned int                     				size_type;
	typedef unsigned long                    				long_type;
	typedef util::Vector_Lite<size_type, 3>  				Dim_Vector;
	typedef util::Vector_Lite<Vec_Int, 3>    				Count_Vector;
	typedef util::Vector_Lite<double, 3>     				Space_Vector;
	typedef util::Vector_Lite<Vec_Dbl, 3>    				Cell_Edges;
	typedef util::Vector_Lite<Vec_Dbl, 3>    				Cell_Widths;
    typedef std::vector<std::vector<std::vector<int> > > 	Mat_Id_Vector;
	//@}

public:
	// >>> CONST DATA

    // Spatial dimension of this problem.
    const int d_spacedim;

	// Number of cells in each dimension in this mesh.
	const Dim_Vector d_N;

	// Number of coarse cells in each dimension in this mesh.
	const Dim_Vector d_Nc;

	// Total number of cells in this mesh.
	const long_type d_num_cells;

private:
	// >>> DATA

	// Coarse mesh data isn't used yet, but may be of use later on.

	// Coarse mesh edges.
	Cell_Edges d_coarse_edges;

	// Coarse mesh widths.
	Cell_Widths d_coarse_width;

	// Number of fine mesh per coarse mesh
	Count_Vector d_fine_per_coarse;

	// Fine mesh edges.
	Cell_Edges d_fine_edges;

	// Fine mesh widths.
	Cell_Widths d_fine_width;

	// Inverse fine mesh widths.
	Cell_Widths d_fine_inv_width;

	// Fine mesh material index
	Mat_Id_Vector d_mat_id;

public:

	// Constructor.
	Mesh( SP_input input, SP_element element );

	// >>> PUBLIC INTERFACE

	// Convert (i,j,k) to a cardinal index.
	inline size_type convert(size_type i, size_type j = 0, size_type k = 0) const;

	// Return fine cell width along \e (i,j,k).
	inline double width(size_type ijk, int dimension) const;

	// Return inverse of fine cell width along \e (i,j,k).
	inline double inv_width(size_type ijk, int dimension) const;

	// Cell center along \e (i,j,k).
	inline double center(size_type ijk, int dimension) const;

	// Block width.
	inline Space_Vector width() const;

	//! Low corner of mesh in \e (i,j,k) direction.
	//   double low_corner(int d) const { return d_edges[d].front(); }

	//! Cell edges along a given direction.
	const Vec_Dbl& edges(int d) const { return d_fine_edges[d]; }
};

} // end namespace slabtran


#endif // MESH_HH

//---------------------------------------------------------------------------//
//              end of Mesh.hh
//---------------------------------------------------------------------------//
